home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 September / Enter 09 2006.iso / Internet / SpamExperts Home 1.1 / SpamExperts Home.exe / lib / spamexperts.modules / dns / rdataset.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-07-14  |  10.4 KB  |  317 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''DNS rdatasets (an rdataset is a set of rdatas of a given type and class)'''
  5. import random
  6. import StringIO
  7. import struct
  8. import dns.exception as dns
  9. import dns.rdatatype as dns
  10. import dns.rdataclass as dns
  11. import dns.rdata as dns
  12. import dns.set as dns
  13. SimpleSet = dns.set.Set
  14.  
  15. class DifferingCovers(dns.exception.DNSException):
  16.     '''Raised if an attempt is made to add a SIG/RRSIG whose covered type
  17.     is not the same as that of the other rdatas in the rdataset.'''
  18.     pass
  19.  
  20.  
  21. class IncompatibleTypes(dns.exception.DNSException):
  22.     '''Raised if an attempt is made to add rdata of an incompatible type.'''
  23.     pass
  24.  
  25.  
  26. class Rdataset(dns.set.Set):
  27.     '''A DNS rdataset.
  28.  
  29.     @ivar rdclass: The class of the rdataset
  30.     @type rdclass: int
  31.     @ivar rdtype: The type of the rdataset
  32.     @type rdtype: int
  33.     @ivar covers: The covered type.  Usually this value is
  34.     dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
  35.     dns.rdatatype.RRSIG, then the covers value will be the rdata
  36.     type the SIG/RRSIG covers.  The library treats the SIG and RRSIG
  37.     types as if they were a family of
  38.     types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).  This makes RRSIGs much
  39.     easier to work with than if RRSIGs covering different rdata
  40.     types were aggregated into a single RRSIG rdataset.
  41.     @type covers: int
  42.     @ivar ttl: The DNS TTL (Time To Live) value
  43.     @type ttl: int
  44.     '''
  45.     __slots__ = [
  46.         'rdclass',
  47.         'rdtype',
  48.         'covers',
  49.         'ttl']
  50.     
  51.     def __init__(self, rdclass, rdtype, covers = dns.rdatatype.NONE):
  52.         '''Create a new rdataset of the specified class and type.
  53.  
  54.         @see: the description of the class instance variables for the
  55.         meaning of I{rdclass} and I{rdtype}'''
  56.         super(Rdataset, self).__init__()
  57.         self.rdclass = rdclass
  58.         self.rdtype = rdtype
  59.         self.covers = covers
  60.         self.ttl = 0
  61.  
  62.     
  63.     def _clone(self):
  64.         obj = super(Rdataset, self)._clone()
  65.         obj.rdclass = self.rdclass
  66.         obj.rdtype = self.rdtype
  67.         obj.covers = self.covers
  68.         obj.ttl = self.ttl
  69.         return obj
  70.  
  71.     
  72.     def update_ttl(self, ttl):
  73.         """Set the TTL of the rdataset to be the lesser of the set's current
  74.         TTL or the specified TTL.  If the set contains no rdatas, set the TTL
  75.         to the specified TTL.
  76.         @param ttl: The TTL
  77.         @type ttl: int"""
  78.         if len(self) == 0:
  79.             self.ttl = ttl
  80.         elif ttl < self.ttl:
  81.             self.ttl = ttl
  82.         
  83.  
  84.     
  85.     def add(self, rd, ttl = None):
  86.         '''Add the specified rdata to the rdataset.
  87.  
  88.         If the optional I{ttl} parameter is supplied, then
  89.         self.update_ttl(ttl) will be called prior to adding the rdata.
  90.         
  91.         @param rd: The rdata
  92.         @type rd: dns.rdata.Rdata object
  93.         @param ttl: The TTL
  94.         @type ttl: int'''
  95.         if self.rdclass != rd.rdclass or self.rdtype != rd.rdtype:
  96.             raise IncompatibleTypes
  97.         
  98.         if ttl is not None:
  99.             self.update_ttl(ttl)
  100.         
  101.         if self.rdtype == dns.rdatatype.RRSIG or self.rdtype == dns.rdatatype.SIG:
  102.             covers = rd.covers()
  103.             if len(self) == 0 and self.covers == dns.rdatatype.NONE:
  104.                 self.covers = covers
  105.             elif self.covers != covers:
  106.                 raise DifferingCovers
  107.             
  108.         
  109.         if dns.rdatatype.is_singleton(rd.rdtype) and len(self) > 0:
  110.             self.clear()
  111.         
  112.         super(Rdataset, self).add(rd)
  113.  
  114.     
  115.     def union_update(self, other):
  116.         self.update_ttl(other.ttl)
  117.         super(Rdataset, self).union_update(other)
  118.  
  119.     
  120.     def intersection_update(self, other):
  121.         self.update_ttl(other.ttl)
  122.         super(Rdataset, self).intersection_update(other)
  123.  
  124.     
  125.     def update(self, other):
  126.         '''Add all rdatas in other to self.
  127.  
  128.         @param other: The rdataset from which to update
  129.         @type other: dns.rdataset.Rdataset object'''
  130.         self.update_ttl(other.ttl)
  131.         super(Rdataset, self).update(other)
  132.  
  133.     
  134.     def __repr__(self):
  135.         if self.covers == 0:
  136.             ctext = ''
  137.         else:
  138.             ctext = '(' + dns.rdatatype.to_text(self.covers) + ')'
  139.         return '<DNS ' + dns.rdataclass.to_text(self.rdclass) + ' ' + dns.rdatatype.to_text(self.rdtype) + ctext + ' rdataset>'
  140.  
  141.     
  142.     def __str__(self):
  143.         return self.to_text()
  144.  
  145.     
  146.     def __eq__(self, other):
  147.         '''Two rdatasets are equal if they have the same class, type, and
  148.         covers, and contain the same rdata.
  149.         @rtype: bool'''
  150.         if not isinstance(other, Rdataset):
  151.             return False
  152.         
  153.         if self.rdclass != other.rdclass and self.rdtype != other.rdtype or self.covers != other.covers:
  154.             return False
  155.         
  156.         return super(Rdataset, self).__eq__(other)
  157.  
  158.     
  159.     def __ne__(self, other):
  160.         return not self.__eq__(other)
  161.  
  162.     
  163.     def to_text(self, name = None, origin = None, relativize = True, override_rdclass = None, **kw):
  164.         '''Convert the rdataset into DNS master file format.
  165.  
  166.         @see: L{dns.name.Name.choose_relativity} for more information
  167.         on how I{origin} and I{relativize} determine the way names
  168.         are emitted.
  169.  
  170.         Any additional keyword arguments are passed on to the rdata
  171.         to_text() method.
  172.         
  173.         @param name: If name is not None, emit a RRs with I{name} as
  174.         the owner name.
  175.         @type name: dns.name.Name object
  176.         @param origin: The origin for relative names, or None.
  177.         @type origin: dns.name.Name object
  178.         @param relativize: True if names should names be relativized
  179.         @type relativize: bool'''
  180.         if name is not None:
  181.             name = name.choose_relativity(origin, relativize)
  182.             ntext = str(name)
  183.             pad = ' '
  184.         else:
  185.             ntext = ''
  186.             pad = ''
  187.         s = StringIO.StringIO()
  188.         if override_rdclass is not None:
  189.             rdclass = override_rdclass
  190.         else:
  191.             rdclass = self.rdclass
  192.         if len(self) == 0:
  193.             print >>s, '%s%s%s %s' % (ntext, pad, dns.rdataclass.to_text(rdclass), dns.rdatatype.to_text(self.rdtype))
  194.         else:
  195.             for rd in self:
  196.                 print >>s, '%s%s%d %s %s %s' % (ntext, pad, self.ttl, dns.rdataclass.to_text(rdclass), dns.rdatatype.to_text(self.rdtype), rd.to_text(origin = origin, relativize = relativize, **kw))
  197.             
  198.         return s.getvalue()[:-1]
  199.  
  200.     
  201.     def to_wire(self, name, file, compress = None, origin = None, override_rdclass = None, want_shuffle = True):
  202.         '''Convert the rdataset to wire format.
  203.  
  204.         @param name: The owner name of the RRset that will be emitted
  205.         @type name: dns.name.Name object
  206.         @param file: The file to which the wire format data will be appended
  207.         @type file: file
  208.         @param compress: The compression table to use; the default is None.
  209.         @type compress: dict
  210.         @param origin: The origin to be appended to any relative names when
  211.         they are emitted.  The default is None.
  212.         @returns: the number of records emitted
  213.         @rtype: int
  214.         '''
  215.         if override_rdclass is not None:
  216.             rdclass = override_rdclass
  217.             want_shuffle = False
  218.         else:
  219.             rdclass = self.rdclass
  220.         file.seek(0, 2)
  221.         if len(self) == 0:
  222.             name.to_wire(file, compress, origin)
  223.             stuff = struct.pack('!HHIH', self.rdtype, rdclass, 0, 0)
  224.             file.write(stuff)
  225.             return 1
  226.         elif want_shuffle:
  227.             l = list(self)
  228.             random.shuffle(l)
  229.         else:
  230.             l = self
  231.         for rd in l:
  232.             name.to_wire(file, compress, origin)
  233.             stuff = struct.pack('!HHIH', self.rdtype, rdclass, self.ttl, 0)
  234.             file.write(stuff)
  235.             start = file.tell()
  236.             rd.to_wire(file, compress, origin)
  237.             end = file.tell()
  238.             if not end - start < 65536:
  239.                 raise AssertionError
  240.             file.seek(start - 2)
  241.             stuff = struct.pack('!H', end - start)
  242.             file.write(stuff)
  243.             file.seek(0, 2)
  244.         
  245.         return len(self)
  246.  
  247.     
  248.     def match(self, rdclass, rdtype, covers):
  249.         '''Returns True if this rdataset matches the specified class, type,
  250.         and covers'''
  251.         if self.rdclass == rdclass and self.rdtype == rdtype and self.covers == covers:
  252.             return True
  253.         
  254.         return False
  255.  
  256.  
  257.  
  258. def from_text_list(rdclass, rdtype, ttl, text_rdatas):
  259.     '''Create an rdataset with the specified class, type, and TTL, and with
  260.     the specified list of rdatas in text format.
  261.  
  262.     @rtype: dns.rdataset.Rdataset object
  263.     '''
  264.     if isinstance(rdclass, str):
  265.         rdclass = dns.rdataclass.from_text(rdclass)
  266.     
  267.     if isinstance(rdtype, str):
  268.         rdtype = dns.rdatatype.from_text(rdtype)
  269.     
  270.     r = Rdataset(rdclass, rdtype)
  271.     r.update_ttl(ttl)
  272.     for t in text_rdatas:
  273.         rd = dns.rdata.from_text(r.rdclass, r.rdtype, t)
  274.         r.add(rd)
  275.     
  276.     return r
  277.  
  278.  
  279. def from_text(rdclass, rdtype, ttl, *text_rdatas):
  280.     '''Create an rdataset with the specified class, type, and TTL, and with
  281.     the specified rdatas in text format.
  282.     
  283.     @rtype: dns.rdataset.Rdataset object
  284.     '''
  285.     return from_text_list(rdclass, rdtype, ttl, text_rdatas)
  286.  
  287.  
  288. def from_rdata_list(ttl, rdatas):
  289.     '''Create an rdataset with the specified TTL, and with
  290.     the specified list of rdata objects.
  291.     
  292.     @rtype: dns.rdataset.Rdataset object
  293.     '''
  294.     if len(rdatas) == 0:
  295.         raise ValueError, 'rdata list must not be empty'
  296.     
  297.     r = None
  298.     for rd in rdatas:
  299.         if r is None:
  300.             r = Rdataset(rd.rdclass, rd.rdtype)
  301.             r.update_ttl(ttl)
  302.             first_time = False
  303.         
  304.         r.add(rd)
  305.     
  306.     return r
  307.  
  308.  
  309. def from_rdata(ttl, *rdatas):
  310.     '''Create an rdataset with the specified TTL, and with
  311.     the specified rdata objects.
  312.     
  313.     @rtype: dns.rdataset.Rdataset object
  314.     '''
  315.     return from_rdata_list(ttl, rdatas)
  316.  
  317.